/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package digitaldreamers.libraries.games.clients.gameclient.gameui.implementation;

import digitaldreamers.libraries.games.clients.gameclient.gameui.abstracts.IScreenManager;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import javax.swing.JPanel;

/**
 *
 * @author DaoLe
 */
public class RenderPanel extends JPanel implements Runnable {
    private static final int FPS = 60;
    private static final int SLEEP_TIME = 1000 / FPS;
    
    private WindowsGame m_Game = null;
    private BufferedImage m_FrameBuffer = null;
    //private KeyboardHandler m_KeyboardHandler = null;
    //private MouseHandler m_MouseHandler = null;
    private Thread m_RenderThread = null;
    private volatile boolean m_bIsRunning = false;
    
    public RenderPanel(WindowsGame game) {
        this(game.getWidth(), game.getHeight(), game);
    }
    
    public RenderPanel(int iScreenWidth, int iScreenHeight, WindowsGame game) {
        m_Game = game;
        m_FrameBuffer = new BufferedImage(iScreenWidth, iScreenHeight, BufferedImage.TYPE_4BYTE_ABGR);
        setLayout(null);
        setSize(iScreenWidth, iScreenHeight);
        setVisible(true);
    }
    
    public WindowsGame getGame() {
        return m_Game;
    }
    
    public BufferedImage getFrameBuffer() {
        return m_FrameBuffer;
    }
    
    /*
    public KeyboardHandler getKeyboardHandler() {
        return keyboardHandler;
    }
    
    public MouseHandler getMouseHandler() {
        return touchHandler;
    }
    */
    
    public void resume() { 
        m_bIsRunning = true;
        m_RenderThread = new Thread(this);
        m_RenderThread.start();         
    }
    
    public void pause() {                        
        m_bIsRunning = false;                        
        while(true) {
            try {
                m_RenderThread.join();
                break;
            } catch (InterruptedException e) {
            }
        }
    }
    
    public void run() {
        IScreenManager screenManager = m_Game.getScreenManager();
        long lStartTime = System.currentTimeMillis();
        while(m_bIsRunning) {
            long lFrameStart = System.currentTimeMillis();
            long lDeltaTime = lFrameStart - lStartTime;
            lStartTime = lFrameStart;
            screenManager.update(lDeltaTime);
            //screenManager.present(lDeltaTime);
            repaint();
            long lFrameEnd = System.currentTimeMillis();
            long lFrameTime = lFrameEnd - lFrameStart;
            if(lFrameTime < SLEEP_TIME) {
                try {
                    Thread.sleep(SLEEP_TIME - lFrameTime);
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
            }
        }
        
        //Debug
        System.out.println("Game loop thread exited.");
    }

    @Override
    public void paintComponent(Graphics grphcs) {
        super.paintComponent(grphcs);
        grphcs.setColor(Color.BLACK);
        grphcs.fillRect(0, 0, getWidth(), getHeight());
        IScreenManager screenManager = m_Game.getScreenManager();
        GameScreen currentScreen = (GameScreen)screenManager.getCurrentScreen();
        if(currentScreen != null) {
            BufferedImage bufferedImage = currentScreen.getBufferedImage();
            grphcs.drawImage(bufferedImage, 0, 0, getWidth(), getHeight(), 0, 0, bufferedImage.getWidth(), bufferedImage.getHeight(), null);
        }
    }
    
    void setScreen(GameScreen screen) {
        removeAll();
        add(screen);
    }
}
